/* eslint-disable camelcase */
/*
 * description:编辑器主逻辑文件
 */
import { ifs, Tsrv } from './config';
// 开始节点接口
interface I_begin {
  type: string;
  nodeID: string;
  nodeName: string;
  explain: string;
}
// 结束节点接口
interface I_end {
  type: string;
  nodeID: string;
  nodeName: string;
  explain: string;
}
// 条件节点接口
interface I_if {
  type: string;
  nodeID: string;
  nodeName: string;
  explain?: string;
  expr?: string;
}
// 当节点接口
interface I_switch {
  type: string;
  nodeID: string;
  nodeName: string;
  exprs: { edgeID: string; expr: string; explain: string }[];
}
// 表达式节点接口
interface I_expr {
  type: string;
  nodeID: string;
  nodeName: string;
  explain: string;
  expr: string;
}

// 组件类型公用类型
type T_compsType = I_begin | I_end | I_if | I_expr | I_switch;
interface I_nodeAttrData {
  comps: T_compsType[];
}
// 基础信息接口
interface I_baseInfo {
  // 规则库编号
  id: string;
  rule_number: string;
  f_name: string;
  version: string;
  f_comment: string;
  f_trigger: string;
}

// 规则属性传参接口
interface I_ruleArg {
  name: string;
  dataType: string;
}

// 规则属性接口
interface I_ruleAttrData {
  baseInfo: I_baseInfo;
  inArg: I_ruleArg[];
  outArg: I_ruleArg[];
}

interface I_RuleData extends I_baseInfo {
  rule_attr: I_ruleAttrData;
  input_arg: I_ruleArg[];
  output_arg: I_ruleArg[];
  graph_data: any;
  node_attr: I_nodeAttrData;
  dsl_input_arg: string;
  dsl_output_arg: string;
  dsl_code: string;
  f_enabled: boolean;
  class_code: string;
  source_code: any;
}
// type comp 编译脚本 debug 调试脚本  addPool 加入线程 removePool 移出线程 audit cancelAudit
type TruleReq = {
  type: string;
  ruleLibID: string;
  ruleNo?: string;
  debugOptions?: any;
};

class T_ruleEditor {
  private _nodeAttr: I_nodeAttrData;

  private _ruleAttr: I_ruleAttrData;

  private _graph: any;

  private G_compID: string;

  private GT_compBox: ifs.I_compBox;

  private G_compBoxInfo: ifs.I_compBoxInfo;

  private tableName: string = '_sys_rule_lib';

  private _graphEditorState: string = `none`; // 画面状态 new modify none

  constructor(compBoxInfo: ifs.I_compBoxInfo) {
    this.GT_compBox = compBoxInfo.TcompBox;
    this.G_compID = compBoxInfo.compID;
    this.G_compBoxInfo = compBoxInfo;
    this._ruleAttr = {
      baseInfo: {
        id: '',
        rule_number: '',
        f_name: '',
        version: '',
        f_comment: '',
        f_trigger: ''
      },
      inArg: [],
      outArg: []
    };
    this._nodeAttr = { comps: [] };
  }

  //  设置节点属性
  public set nodeAttr(data: I_nodeAttrData) {
    this._nodeAttr = data;
  }

  //  取节点属性
  public get nodeAttr(): I_nodeAttrData {
    return this._nodeAttr;
  }

  //  设置规则属性
  public set ruleAttr(data: I_ruleAttrData) {
    this._ruleAttr = data;
    // const L_ruleAttr = this.GT_compBox.getCompMergeName(
    //   this.G_compID,
    //   `ruleAttr`
    // );
    // this._ruleAttr = data;
    // L_ruleAttr.setFormItem(this._ruleAttr.baseInfo);
  }

  //  取规则属性
  public get ruleAttr(): I_ruleAttrData {
    return this._ruleAttr;
  }

  public get graph(): any {
    return this._graph;
  }

  public set graph(d: any) {
    this._graph = d;
  }

  //  初始化主编辑器
  public initEdirot() {
    (async () => {
      await this.initRuleAttr(); // 清除规则属性 初始化验编号
      this.initNodeAttr(); // 清除节点属性
    })();
  }

  //  初始化规则属性
  public async initRuleAttr() {
    const L_ruleAttr = this.GT_compBox.getCompMergeName(
      this.G_compID,
      `ruleAttr`
    );
    // 规则库编号 长12位 10进制
    const L_ruleNum: string = `RE_${Tsrv.utils.custUUID(12, 10)}`;
    const L_baseInfo: I_baseInfo = {
      id: await Tsrv.getSnowIDFmtStr(),
      // 规则库表行ID
      rule_number: L_ruleNum,
      f_name: ``,
      version: ``,
      f_comment: ``,
      f_trigger: ``
    };

    const L_d: I_ruleAttrData = {
      baseInfo: L_baseInfo,
      inArg: [],
      outArg: []
    };
    L_ruleAttr.setData(L_d);
    L_ruleAttr.G_inData = [];
    L_ruleAttr.G_outData = [];
  }

  //  初始化节点属性
  initNodeAttr() {
    this._nodeAttr = { comps: [] };
  }

  //  记录流程编辑器状态
  public set graphEditorState(P_s: string) {
    this._graphEditorState = P_s;
    const L_ruleAttr = this.GT_compBox.getCompMergeName(
      this.G_compID,
      `ruleAttr`
    );
    const L_nodeAttr = this.GT_compBox.getCompMergeName(
      this.G_compID,
      `nodeAttr`
    );
    if (P_s === `none`) {
      L_ruleAttr.G_readonly = true;
      L_nodeAttr.setCompDisabled(true);
    } else {
      L_ruleAttr.G_readonly = false;
      L_nodeAttr.setCompDisabled(false);
    }
  }

  //  获取流程图编辑器状态
  public get graphEditorState(): string {
    return this._graphEditorState;
  }

  //  节点数据
  public getNodeAttrData(nodeID: string): T_compsType {
    return this._nodeAttr.comps.filter(item => item.nodeID === nodeID)[0];
  }

  //  设置节点数据 节点数据存放在T_ruleEditor._nodeAttr.comps
  public setNodeAttrData(data: T_compsType) {
    if (!data[`nodeID`]) {
      return;
    }
    if (this.getNodeAttrData(data.nodeID)) {
      for (const idx in this._nodeAttr.comps) {
        if (this._nodeAttr.comps[idx].nodeID === data.nodeID) {
          this._nodeAttr.comps[idx] = data;
          break;
        }
      }
    } else {
      this._nodeAttr.comps.push(data);
    }
  }

  public removeNodeComp(nodeID: string) {
    for (const idx in this._nodeAttr.comps) {
      if (this._nodeAttr.comps[idx].nodeID === nodeID) {
        this._nodeAttr.comps.splice(+idx, 1);
        break;
      }
    }
  }

  // 新增修改
  public async saveData(): Promise<[boolean, string]> {
    const L_data: I_RuleData = {
      id: this.ruleAttr.baseInfo.id,
      rule_number: this.ruleAttr.baseInfo.rule_number,
      f_name: this.ruleAttr.baseInfo.f_name,
      version: this.ruleAttr.baseInfo.version,
      f_comment: this.ruleAttr.baseInfo.f_comment,
      f_trigger: this.ruleAttr.baseInfo.f_trigger,
      input_arg: this.ruleAttr.inArg,
      output_arg: this.ruleAttr.outArg,
      graph_data: this.graph,
      node_attr: this.nodeAttr,
      rule_attr: this.ruleAttr,
      class_code: 'default',
      f_enabled: false,
      dsl_code: '',
      dsl_input_arg: '',
      dsl_output_arg: '',
      source_code: {
        data: this.graph,
        nodeAttr: this.nodeAttr,
        ruleAttr: this.ruleAttr
      }
    };
    const msg: string = this.saveDataCheck(L_data);
    if (msg) {
      return [false, msg];
    }
    if (this.graphEditorState === 'new') {
      const [b, res, err] = await Tsrv.ruleNew(this.tableName, L_data);
      return [b, err];
    }
    if (this.graphEditorState === 'modify') {
      const [b, res, err] = await Tsrv.ruleModify(
        this.tableName,
        { $set: L_data },
        { id: L_data.id }
      );
      return [b, err];
    }
    return [false, '-559,FE,90'];
  }

  //  数据保存前检查
  public saveDataCheck(data: I_RuleData): string {
    if (data.f_name === ``) {
      // 属性规则名称不存在
      return `属性规则名称不存在`;
    }
    // 属性规则编号不存在
    if (data.rule_number === ``) {
      return `属性规则编号不存在`;
    }
    // 属性规则触发为空
    if (data.f_trigger === ``) {
      return `属性规则触发为空`;
    }
    // 没有图形数据
    if (Tsrv.utils.isEmpty(data.graph_data)) {
      return `没有图形数据`;
    }

    return ``;
  }

  //  打开数据时统一设置数据入口
  public setEditorData(data) {
    const L_ruleAttr = this.GT_compBox.getCompMergeName(
      this.G_compID,
      `ruleAttr`
    );
    const L_nodeAttr = this.GT_compBox.getCompMergeName(
      this.G_compID,
      `nodeAttr`
    );
    const ruleAttrV: any = { baseInfo: {}, inArg: [], outArg: [] };

    L_ruleAttr.setData(ruleAttrV);
    L_ruleAttr.setData(data[`rule_attr`]);

    // setData 会将数据送到本类属性_nodeAttr
    L_nodeAttr.setData(data[`node_attr`]);

    this.setGraphData(data['graph_data']);
  }

  // type comp 编译脚本 debug 调试脚本  addPool 加入线程 removePool 移出线程 audit cancelAudit
  public async ruleWebReq(
    apiName: string,
    ruleNo?: string,
    debugOptions?: any
  ): Promise<[ifs.I_setDataRes, any]> {
    const L_req: TruleReq = {
      type: apiName,
      ruleLibID: this.ruleAttr.baseInfo.id,
      debugOptions
    };
    apiName === `isInPoolList` && (L_req.ruleNo = ruleNo);
    const url = Tsrv.lexicon.url.rulectl;
    return Tsrv.standardPostReq<ifs.I_setDataRes, TruleReq>(L_req, url);
  }

  setGraphData(d: any) {
    this.GT_compBox.getCompMergeName(this.G_compID, `ruleEditor`).setGraphData(
      d
    );
  }
}

// 主编辑器接口
interface I_ruleEditor extends T_ruleEditor {}
export {
  I_baseInfo,
  I_begin,
  I_end,
  I_expr,
  I_if,
  I_nodeAttrData,
  I_ruleArg,
  I_ruleAttrData,
  I_ruleEditor,
  I_switch,
  T_ruleEditor
};
